package com.example.cd5160866.modelrecycleview.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * @author cd5160866
 * @date 18/6/10
 */
public class ModelRecyclerAdapterV3<T> extends RecyclerView.Adapter<ModelRecyclerAdapterV3.ModelViewHolder> {
    public static final int TYPE_DEFAULT = 1000;
    private Context mContext;
    private int mLayoutId;
    private Class<? extends ModelViewHolder> mViewHolderClass;
    private List<T> mData = new ArrayList<>();
    private SparseArray<View> mHeaderViews = new SparseArray<>();
    private SparseArray<View> mFooterViews = new SparseArray<>();
    /**
     * 自增的viewType
     */
    private int viewTypeAsc = 0;

    public ModelRecyclerAdapterV3(Context context, Class<? extends ModelViewHolder<T>> mViewHolderClass) {
        this(context, mViewHolderClass, new ArrayList<T>());
    }

    public ModelRecyclerAdapterV3(Context context, Class<? extends ModelViewHolder<T>> mViewHolderClass, List<T> data) {
        this.mData = data;
        this.mContext = context;
        this.mViewHolderClass = mViewHolderClass;
        this.mLayoutId = mViewHolderClass.getAnnotation(RecyclerItemViewId.class).value();
    }

    /**
     * 任何一个viewType 除了默认Item以外都会存在header或footer 的list中，因为是唯一的viewType 在adapter中唯一
     *
     * @param viewType 当这个view 被添加为header或footer adapter为其生成的一个id
     * @return 被添加的header或footer View
     */
    @Nullable
    private View getHeaderOrFooterView(int viewType) {
        View targetView = mHeaderViews.get(viewType);
        if (null != targetView) {
            return targetView;
        } else {
            return mFooterViews.get(viewType);
        }
    }

    @Override
    public ModelViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        ModelViewHolder viewHolder;
        View convertView;
        if (viewType == TYPE_DEFAULT) {
            convertView = LayoutInflater.from(mContext).inflate(mLayoutId, parent, false);
        } else {
            convertView = getHeaderOrFooterView(viewType);
        }
        if (null == convertView) {
            return null;
        }
        try {
            viewHolder = mViewHolderClass.getConstructor(View.class).newInstance(convertView);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("ViewHolder must has a custom (param View type ) constructor");
        }

        viewHolder.viewType = viewType;
        if (viewType == TYPE_DEFAULT) {
            viewHolder.bindButterKnife(convertView);
        }

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ModelViewHolder holder, int position) {
        if (null == holder || null == mData || 0 == mData.size()) {
            return;
        }
        if (holder.viewType != TYPE_DEFAULT) {
            return;
        }
        position = position - mHeaderViews.size();
        if (position < 0 || mData.size() <= position) {
            return;
        }
        holder.update(mData.get(position), this, position);
    }

    /**
     * 除了默认布局样式以外，header和footer 都有一个默认的viewType存于数组中
     *
     * @param position 布局的位置
     * @return header或者footer或 默认布局
     */
    @Override
    public int getItemViewType(int position) {
        if (position <= mHeaderViews.size() - 1) {
            return mHeaderViews.keyAt(position);
        }
        int itemStackWithoutFooterSize = mHeaderViews.size() + mData.size();
        if (itemStackWithoutFooterSize - 1 < position && position <= getItemCount() - 1) {
            return mFooterViews.keyAt(position - itemStackWithoutFooterSize);
        }
        return TYPE_DEFAULT;
    }

    /**
     * item 即recyclerView 真正有的layout个数，即数据的个数+Header的数量+footer的数量
     *
     * @return layout总个数 包含header和footer
     */
    @Override
    public int getItemCount() {
        int itemSize = mData.size();
        itemSize += mHeaderViews.size() + mFooterViews.size();
        return itemSize;
    }

    public Context getContext() {
        return mContext;
    }

    public List<T> getItems() {
        return mData;
    }

    /**
     * 根据 recyclerView 实际的item位置 出去header所占的位置 转化为实际填充数据的位置
     *
     * @param layoutPosition layoutPosition
     * @return 数据的点击位置，如果为-1 说明点击了header或footer
     */
    public int getDataPositionByLayoutPosition(int layoutPosition) {
        //header 除去Header所占的位置
        int dataPosition = layoutPosition - mHeaderViews.size();
        if (Arrays.isEmpty(mData) || dataPosition < 0 || dataPosition >= mData.size()) {
            dataPosition = RecyclerView.NO_POSITION;
        }
        return dataPosition;
    }

    public void add(int position, T data) {
        mData.add(position, data);
        notifyDataSetChanged();
    }

    public void remove(int position) {
        mData.remove(position);
        notifyDataSetChanged();
    }


    public void setItems(List<T> data) {
        mData.clear();
        mData.addAll(data);
        notifyDataSetChanged();

    }

    public void addAll(List<T> data) {
        mData.addAll(data);
        notifyDataSetChanged();
    }

    public void clear() {
        mData.clear();
        notifyDataSetChanged();
    }

    /**
     * 添加一个HeaderView
     *
     * @return adapter为其生成一个自增的viewId 这个id唯一 用于指定header 或footer的 viewType 也是它的唯一标示
     */
    public int addHeaderView(@NonNull View headerView) {
        viewTypeAsc += 1;
        headerView.setId(viewTypeAsc);
        mHeaderViews.append(headerView.getId(), headerView);
        notifyDataSetChanged();
        return viewTypeAsc;
    }

    public void removeHeaderView(@NonNull View headerView) {
        if (mHeaderViews.indexOfValue(headerView) != -1) {
            mHeaderViews.remove(headerView.getId());
            notifyDataSetChanged();
        }
    }

    public int getHeaderViewsCount() {
        return mHeaderViews.size();
    }

    /**
     * 添加一个FooterView
     *
     * @return adapter为其生成一个自增的viewId 这个id唯一 用于指定header 或footer的 viewType 也是它的唯一标示
     */
    public int addFooterView(@NonNull View footerView) {
        viewTypeAsc += 1;
        footerView.setId(viewTypeAsc);
        mFooterViews.append(footerView.getId(), footerView);
        notifyDataSetChanged();
        return viewTypeAsc;
    }

    public void removeFooterView(@NonNull View footerView) {
        if (mFooterViews.indexOfValue(footerView) != -1) {
            mFooterViews.remove(footerView.getId());
            notifyDataSetChanged();
        }
    }

    public int getFooterViewsCount() {
        return mFooterViews.size();
    }

    private Object object;

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public static abstract class ModelViewHolder<T> extends RecyclerView.ViewHolder {

        int viewType;

        public ModelViewHolder(View itemView) {
            super(itemView);
        }

        public abstract void bindButterKnife(View convertView);

        public abstract void update(T item, ModelRecyclerAdapterV3 adapter, int position);

    }
}
